﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ESP.Data
{
    /// <summary>
    ///  command
    /// </summary>
    public class CommandBuilder
    {
        public const string ParameterNamePrefix = "__p_";

        public const string PlaceHolderDelimiter = "@@@";

        /// <summary>
        /// 将还原成字符串的lambda 构建为cmd
        /// </summary>
        /// <param name="template"></param>
        /// <param name="commandParameters"></param>
        /// <returns></returns>
        public static CommandInfo Build(string template, params CommandParameters[] commandParameters)
        {

            List<System.Data.IDataParameter> parameters = new List<System.Data.IDataParameter>();

            Dictionary<string, CommandParameters> dic = new Dictionary<string, CommandParameters>();
            for (var i = commandParameters.Length - 1; i >= 0; i--)
            {
                var p = commandParameters[i];
                if (p == null)
                    continue;
                p.Build();
                parameters.AddRange(p.Parameters);
                dic.Add(p.Token, p);
            }

            StringBuilder builder = new StringBuilder();
            int startPosition = 0;

            while (startPosition >= 0)
            {
                int index = template.IndexOf(PlaceHolderDelimiter, startPosition);
                if (index < 0)
                {
                    builder.Append(template.Substring(startPosition));
                    break;
                }

                builder.Append(template.Substring(startPosition, index - startPosition));
                startPosition = index;

                index += PlaceHolderDelimiter.Length;
                if (startPosition == template.Length)
                    break;

                int index2 = template.IndexOf(PlaceHolderDelimiter, index);
                if (index2 < 0)
                {
                    builder.Append(template.Substring(startPosition));
                    break;
                }

                string placeHolder = template.Substring(index, index2 - index);
                if (placeHolder.Length == 0)
                {
                }
                else if (placeHolder[0] == '#')
                {
                    builder.Append(PlaceHolderDelimiter).Append(placeHolder.Substring(1)).Append(PlaceHolderDelimiter);
                }
                else
                {
                    string mainToken;
                    string subToken = null;
                    int index3 = placeHolder.IndexOf('.');
                    if (index3 > 0)
                    {
                        mainToken = placeHolder.Substring(0, index3);
                        subToken = placeHolder.Substring(index3 + 1);
                    }
                    else
                    {
                        mainToken = placeHolder;
                        subToken = string.Empty;
                    }

                    builder.Append(dic[mainToken].SubParameters[subToken]);
                }

                startPosition = index2 + PlaceHolderDelimiter.Length;
                if (startPosition == template.Length)
                    break;
            }

            return new CommandInfo(builder.ToString(), parameters);
        }

        private static string GetNextPlaceHolder(StringBuilder builder, string template, ref int startIndex)
        {
            int index = template.IndexOf(PlaceHolderDelimiter, startIndex);
            if (index < 0)
            {
                builder.Append(template.Substring(startIndex));
                startIndex = -1;
                return null;
            }

            builder.Append(template.Substring(startIndex, index - startIndex));
            startIndex = index;

            index += PlaceHolderDelimiter.Length;

            int index2 = template.IndexOf(PlaceHolderDelimiter, index);
            if (index2 < 0)
            {
                builder.Append(template.Substring(startIndex));
                startIndex = -1;
                return null;
            }

            string placeHolder = template.Substring(index, index2 - index);

            startIndex = index2 + PlaceHolderDelimiter.Length;
            if (startIndex == template.Length)
                startIndex = -1;

            return placeHolder;
        }
    }


}
